package com.inspur.edp.bef.bizentity.json.operation;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.inspur.edp.bef.bizentity.beenum.BETriggerTimePointType;
import com.inspur.edp.bef.bizentity.beenum.RequestNodeTriggerType;
import com.inspur.edp.bef.bizentity.common.BizEntityJsonConst;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.cef.designtime.api.entity.CustomizationInfo;
import com.inspur.edp.cef.designtime.api.json.CefNames;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.cef.designtime.api.json.SerializerUtils;

import java.io.IOException;
import java.util.EnumSet;

import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;

public abstract class BizOperationDeserializer<T extends BizOperation> extends JsonDeserializer<T> {
	@Override
	public final T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) {
		return deserializeBizOperation(jsonParser);
	}
    protected abstract void beforeDeserializeBizoperation(BizOperation op);

	private final T deserializeBizOperation(JsonParser jsonParser) {
		T op = createBizOp();
        op.setIsRef(false);
        op.setDescription("");
        op.setComponentId("");
        op.setComponentName("");
        op.setComponentPkgName("");
        op.setIsVisible(false);
        op.setBelongModelID("");
        op.setIsGenerateComponent(true);
        SerializerUtils.readStartObject(jsonParser);

        beforeDeserializeBizoperation(op);

		while (jsonParser.getCurrentToken() == FIELD_NAME) {
			String propName = SerializerUtils.readPropertyName(jsonParser);
			readPropertyValue(op, propName, jsonParser);
		}
		SerializerUtils.readEndObject(jsonParser);

		return op;
	}

	private void readPropertyValue(BizOperation op, String propName, JsonParser jsonParser) {
		switch (propName) {
			case CommonModelNames.ID:
				op.setID(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case CommonModelNames.Code:
				op.setCode(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case CommonModelNames.Name:
				op.setName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case BizEntityJsonConst.Description:
				op.setDescription(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case BizEntityJsonConst.ComponentId:
				op.setComponentId(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case BizEntityJsonConst.ComponentName:
				op.setComponentName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case BizEntityJsonConst.ComponentPkgName:
				op.setComponentPkgName(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case BizEntityJsonConst.IsVisible:
				op.setIsVisible(SerializerUtils.readPropertyValue_boolean(jsonParser));
				break;
			case BizEntityJsonConst.OpType:
				SerializerUtils.readPropertyValue_String(jsonParser);
				break;
			case BizEntityJsonConst.BelongModelId:
				op.setBelongModelID(SerializerUtils.readPropertyValue_String(jsonParser));
				break;
			case BizEntityJsonConst.IsRef:
				op.setIsRef(SerializerUtils.readPropertyValue_boolean(jsonParser));
				break;
			case BizEntityJsonConst.IsGenerateComponent:
				op.setIsGenerateComponent(SerializerUtils.readPropertyValue_boolean(jsonParser));
				break;
			case CefNames.CustomizationInfo:
				op.setCustomizationInfo(SerializerUtils.readPropertyValue_Object(CustomizationInfo.class,jsonParser));
				try {
					jsonParser.nextToken();
				} catch (IOException e) {
					throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0002, e, "BizOperationDeserializer", propName);
				}
				break;
			default:
				if (!readExtendOpProperty(op, propName, jsonParser)) {
					throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0064, "BizOperationDeserializer", propName);
				}
		}
	}

	protected boolean readExtendOpProperty(BizOperation op, String propName, JsonParser jsonParser) {
		return false;
	}

	protected abstract T createBizOp();

	public static EnumSet<RequestNodeTriggerType> readRequestNodeTriggerType(JsonParser jsonParser) {
		EnumSet<RequestNodeTriggerType> result = EnumSet.noneOf(RequestNodeTriggerType.class);
		int intValueSum = SerializerUtils.readPropertyValue_Integer(jsonParser);
		RequestNodeTriggerType[] values = RequestNodeTriggerType.values();
		// 不包含none
		for (int i = values.length - 1; i > 0; i--) {
			RequestNodeTriggerType value = values[i];
			if (intValueSum > 0 && intValueSum >= value.getValue()) {
				result.add(value);
				intValueSum -= value.getValue();
			}
		}
		return result;
	}

	public static EnumSet<BETriggerTimePointType> readBETriggerTimePointType(JsonParser jsonParser) {
		EnumSet<BETriggerTimePointType> result = EnumSet.noneOf(BETriggerTimePointType.class);
		int intValueSum = SerializerUtils.readPropertyValue_Integer(jsonParser);
		BETriggerTimePointType[] values = BETriggerTimePointType.values();
		// 不包含none
		for (int i = values.length - 1; i > 0; i--) {
			BETriggerTimePointType value = values[i];
			if (intValueSum > 0 && intValueSum >= value.getValue()) {
				result.add(value);
				intValueSum -= value.getValue();
			}
		}
		return result;
	}
}
